package com.crazy.controller.sys;

import static com.crazy.common.page.Pager.DEFAULT_COUNT;
import static org.hibernate.criterion.Order.asc;
import static org.hibernate.criterion.Order.desc;
import static org.springframework.validation.ValidationUtils.rejectIfEmptyOrWhitespace;

import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.springframework.data.domain.Page;
import org.springframework.security.web.bind.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.crazy.common.constants.Const;
import com.crazy.entity.sys.PubResource;
import com.crazy.entity.sys.PubRole;
import com.crazy.entity.sys.PubUser;
import com.crazy.service.sys.PubResourceService;
import com.crazy.service.sys.PubRoleService;

/**
 * 角色控制器
 * 
 * @author Zhang Weiwei
 * @since 2013-9-19下午2:46:47
 */
@Controller
@RequestMapping("/sys/role")
public class PubRoleController {
	private static String VIEWNAME = "sys/role/";
	private static final String LISTURL = "sys/role/list";
	private static final String SUCCESS = "redirect:/success.jsp";
	@Inject
	private PubRoleService roleService;
	@Inject
	private PubResourceService resService;

	/**
	 * 显示角色列表
	 * 
	 * @since 2013-9-25下午1:17:37
	 */
	@RequestMapping("/list")
	public String list(Integer pageNo, Model model) {
		Page<PubRole> pager = this.roleService.findAll(pageNo, DEFAULT_COUNT,
				desc("createTime"));
		model.addAttribute("pager", pager);
		return VIEWNAME.concat("list");
	}

	/**
	 * 跳转到添加角色页面
	 * 
	 * @since 2013-9-25下午1:17:18
	 */
	@RequestMapping("/add")
	public String toAdd(Model model) {
		List<PubResource> list = this.resService.findByProperty("enabled",
				Const.ENABLE.getStatus(), asc("priority"), asc("pubResource"));
		String jsonString = this.resService.listToJsonStringForAdd(list);
		PubRole role = new PubRole();
		role.setEnabled(Const.ENABLE.getStatus());
		model.addAttribute("jsonString", jsonString);
		model.addAttribute("role", role);
		return VIEWNAME.concat("add");
	}

	/**
	 * 添加角色
	 * 
	 * @since 2013-9-25下午1:17:08
	 */
	@RequestMapping("/doAdd")
	public String doAdd(@ModelAttribute("role") PubRole role, Errors errors,
			@AuthenticationPrincipal PubUser user, Model model) {
		if (this.validate(errors)) {
			List<PubResource> list = this.resService.findByProperty("enabled",
					Const.ENABLE.getStatus(), asc("priority"), asc("pubResource"));
			String jsonString = this.resService.listToJsonStringForAdd(list);
			model.addAttribute("jsonString", jsonString);
			model.addAttribute("role", role);
			return VIEWNAME.concat("add");
		}
		if (user != null) {
			role.setCreator(user.getUserAccount());
		}
		role.setCreateTime(new Date());
		this.roleService.save(role);
		model.addAttribute("url", LISTURL);
		return SUCCESS;
	}

	/**
	 * 跳转到修改角色页面
	 * 
	 * @since 2013-9-25下午1:16:52
	 */
	@RequestMapping("/update/{id}")
	public String toUpdate(@PathVariable String id, Model model) {
		PubRole role = this.roleService.get(id);
		List<PubResource> list = this.resService.findByProperty("enabled",
				Const.ENABLE.getStatus(), asc("priority"), asc("pubResource"));
		String jsonString = this.roleService.listToJsonStringForUpdate(list,
				role.getPubResources());
		model.addAttribute("jsonString", jsonString);
		model.addAttribute("role", role);
		return VIEWNAME.concat("update");
	}

	/**
	 * 修改角色
	 * 
	 * @since 2013-9-25下午1:16:32
	 */
	@RequestMapping("/doUpdate")
	public String doUpdate(@ModelAttribute("role") PubRole role, Errors errors,
			Model model) {
		if (this.validate(errors)) {
			List<PubResource> list = this.resService.findByProperty("enabled",
					Const.ENABLE.getStatus(), asc("priority"), asc("pubResource"));
			String jsonString = this.roleService.listToJsonStringForUpdate(
					list, role.getPubResources());
			model.addAttribute("jsonString", jsonString);
			model.addAttribute("role", role);
			return VIEWNAME.concat("update");
		}
		PubRole entity = this.roleService.get(role.getRoleId());
		entity.setEnabled(role.getEnabled());
		entity.setRoleDesc(role.getRoleDesc());
		entity.setRoleName(role.getRoleName());
		entity.setPubResources(role.getPubResources());
		this.roleService.update(entity);
		model.addAttribute("url", LISTURL);
		return SUCCESS;
	}

	/**
	 * 删除角色
	 * 
	 * @since 2013-9-25下午1:16:11
	 */
	@RequestMapping("/delete/{id}")
	public String delete(@PathVariable String id, Model model) {
		this.roleService.deleteByPK(id);
		model.addAttribute("url", LISTURL);
		return SUCCESS;
	}

	/**
	 * 验证角色对象
	 * 
	 * @since 2013-11-10下午6:21:53
	 */
	@SuppressWarnings("rawtypes")
	private boolean validate(Errors errors) {
		rejectIfEmptyOrWhitespace(errors, "roleName", "roleName.isNull");
		Object value = errors.getFieldValue("pubResources");
		if (value == null) {
			errors.rejectValue("pubResources", "pubResources.isNull");
		} else {
			if (value instanceof Collection) {
				if (((Collection) value).isEmpty()) {
					errors.rejectValue("pubResources", "pubResources.isNull");
				}
			}
		}
		return errors.hasErrors();
	}

	@ModelAttribute("status")
	public Map<Integer, String> status() {
		Map<Integer, String> map = new LinkedHashMap<>();
		map.put(Const.ENABLE.getStatus(), Const.ENABLE.getName());
		map.put(Const.DISABLED.getStatus(), Const.DISABLED.getName());
		return map;
	}
}
